package com.imooc.controller;

import com.imooc.config.ProjectUrlConfig;
import com.imooc.enums.ResultEnum;
import com.imooc.exception.SellException;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.net.URLEncoder;

/**
 *
 * 第三方sdk整合的方式获取access_token
 *
 * 需要引入第三方的pom依赖
 * <dependency>
 * 			<groupId>com.github.binarywang</groupId>
 * 			<artifactId>weixin-java-mp</artifactId>
 * 			<version>2.7.0</version>
 * 	</dependency>
 *
 * 	    // 分为两步;1、主动向微信端发起请求，接收微信端的回调参数
 *     // 定义两方法;一个是主动向微信端发起请求，一个是被动接收微信的回调请求
 */
@Controller
@RequestMapping("/wechat")
@Slf4j
public class WechatController {

    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private WxMpService wxOpenService;

    @Autowired
    private ProjectUrlConfig projectUrlConfig;
    
    /**
     *  用户访问页面之前，先要验证微信是否登录
     *  http://域名/sell/wechat/authorize?returnUrl=http://sell.com/#/
     * 我们主动调用，用于向微信端发起请求，在回调的方法中获得我们想要的数据
     * @param returnUrl
     * @return
     */
    @GetMapping("/authorize")
    public String authorize(@RequestParam("returnUrl") String returnUrl) {
        // 微信回调的地址
        String url = projectUrlConfig.getWechatMpAuthorize() + "/sell/wechat/userInfo";
        String redirectUrl = wxMpService.oauth2buildAuthorizationUrl(url, WxConsts.OAUTH2_SCOPE_USER_INFO, URLEncoder.encode(returnUrl));
       
        // 拼接的获取code的请求
        // https://open.weixin.qq.com/connect/oauth2/authorize?appid=xxxxxx&redirect_uri=http://test.xxxxxx.com/sell/weixin/auth&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
        return "redirect:" + redirectUrl;
    }

    
    /**
     *
     * http://sell.com//sell/wechat/userInfo?code=061VxS691VYEkN1ryk791Hxxxxxxxxxx&state=http://sell.com/#/
     * 将前端的 index.js配置为： sellUrl: 'http://sell.com'
     * 微信官方的回调地址，由微信端调用，返给我们需要的数据，供我们使用
     * 参数1 ：code
     * 参数2：state
     */
    @GetMapping("/userInfo")
    public String userInfo(@RequestParam("code") String code,
                         @RequestParam("state") String returnUrl) {
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken = new WxMpOAuth2AccessToken();
        
        try {
            wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
        } catch (WxErrorException e) {
            log.error("【微信网页授权】{}", e);
            throw new SellException(ResultEnum.WECHAT_MP_ERROR.getCode(), e.getError().getErrorMsg());
        }

        String openId = wxMpOAuth2AccessToken.getOpenId();

        return "redirect:" + returnUrl + "?openid=" + openId;
    }

    @GetMapping("/qrAuthorize")
    public String qrAuthorize(@RequestParam("returnUrl") String returnUrl) {
        String url = projectUrlConfig.getWechatOpenAuthorize() + "/sell/wechat/qrUserInfo";
        String redirectUrl = wxOpenService.buildQrConnectUrl(url, WxConsts.QRCONNECT_SCOPE_SNSAPI_LOGIN, URLEncoder.encode(returnUrl));
        return "redirect:" + redirectUrl;
    }

    @GetMapping("/qrUserInfo")
    public String qrUserInfo(@RequestParam("code") String code,
                             @RequestParam("state") String returnUrl) {
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken = new WxMpOAuth2AccessToken();
        try {
            wxMpOAuth2AccessToken = wxOpenService.oauth2getAccessToken(code);
        } catch (WxErrorException e) {
            log.error("【微信网页授权】{}", e);
            throw new SellException(ResultEnum.WECHAT_MP_ERROR.getCode(), e.getError().getErrorMsg());
        }
        log.info("wxMpOAuth2AccessToken={}", wxMpOAuth2AccessToken);
        String openId = wxMpOAuth2AccessToken.getOpenId();

        //openId写到cookie里
        return "redirect:" + returnUrl + "?openid=" + openId;
    }
}
